package com.project.personalfundmanager.client;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.extjs.gxt.ui.client.binding.FormBinding;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.project.personalfundmanager.client.common.Const;
import com.project.personalfundmanager.client.common.GlobalRegister;
import com.project.personalfundmanager.client.common.UIHelper;
import com.project.personalfundmanager.client.facebook.Callback;
import com.project.personalfundmanager.client.facebook.JSOModel;
import com.project.personalfundmanager.client.listeners.CalculateTaxListener;
import com.project.personalfundmanager.client.taxitems.ParentItem;
import com.project.personalfundmanager.client.taxitems.Section80CItem;
import com.project.personalfundmanager.shared.models.PayableTaxModel;
import com.project.personalfundmanager.shared.models.Section80CModel;
import com.project.personalfundmanager.shared.models.TaxInfoGroupModel;

@SuppressWarnings( "unchecked" )
public class CalculatedTaxPanel extends ContentPanel
{
	private List<ParentItem> items;
	private TaxInfoGroupModel groupModel;
	private boolean isSeniorCitizen;
	private boolean isWoman;

	Map<Integer, Integer> slabs = getSlabs();
	private FormPanel taxCalculationPanel;

	public CalculatedTaxPanel( boolean isWoman, boolean isSeniorCitizen )
	{
		items = GlobalRegister.getPanelItems();
		groupModel = GlobalRegister.getTaxGroupModel();
		this.isWoman = isWoman;
		this.isSeniorCitizen = isSeniorCitizen;
	}

	Widget getPanel( CalculateTaxListener listener )
	{
		setHeading( "Calculated Tax" );
		for ( ContentPanel tabItem : items )
		{
			addCollapsiblePanel( tabItem );
		}
		addTaxCalculationPanel();
		addNavigationBar( listener );
		countTax();
		bind();
		return this;
	}

	private void addNavigationBar( final CalculateTaxListener listener )
	{
		ButtonBar buttonBar = new ButtonBar();
		buttonBar.setStyleAttribute( "marginTop", "5px" );
		buttonBar.setStyleAttribute( "marginBottom", "5px" );
		buttonBar.setStyleAttribute( "marginLeft", "10px" );
		buttonBar.setSpacing( 10 );
		buttonBar.add( new Button( "Back", new SelectionListener<ButtonEvent>()
		{
			public void componentSelected( ButtonEvent ce )
			{
				listener.back();
			}
		} ) );

		buttonBar.add( new Button( "Submit to IT Department", new SelectionListener<ButtonEvent>()
		{
			public void componentSelected( ButtonEvent ce )
			{
				GlobalRegister.getFbCore().executeFql( "select email from user where uid = me()", new Callback<JavaScriptObject>()
				{
					public void onSuccess( JavaScriptObject result )
					{
						JSOModel cast = result.cast();
						String value = cast.getObject( "0" ).get( "email" );
						GreetingServiceAsync async = ( GreetingServiceAsync ) GWT.create( GreetingService.class );
						async.sendMail( value, new Callback<Boolean>()
						{
							public void onSuccess( Boolean result )
							{
								MessageBox.info( "Information", "Mail" + ( result ? " sent" : " didn't send" ) + " successfully.", null );
							}
						} );
					}
				} );
			}
		} ) );

		buttonBar.add( new Button( "Investment Return Planning", new SelectionListener<ButtonEvent>()
		{
			public void componentSelected( ButtonEvent ce )
			{
				Window window = new Window();
				window.setSize( 725, 425 );
				Image image = new Image();
				image.setUrl( "http://chart.apis.google.com/chart?chf=bg,lg,0,BBCCED,0&chxl=0:|PF|LIC|POSS|NSC+|NSS+|ELSS|FD|NHB|IB|1:|0|1|2|3|4|5|6|7|8|9|10&chxp=0,1,2,3,4,5,6,7,8,9|1,0,1,2,3,4,5,6,7,8,9,10&chxr=0,1,9|1,0,10&chxs=0,990066,11.5,0,l,676767|1,AA0033,11.5,0,l,676767&chxt=x,r&chs=700x400&cht=lc&chco=008000,0000FF,FF0000&chds=0,20,0,10,0,10&chd=t:9,7,8,8.5,7.5,20,8,7,8|5,9,8,6,5,3,5,7,5|3,2,1,1,1,8,5,2,4&chdl=Return+(+Percentage+)|Duration+(+Years+)|Risk+(+Factor+)&chdlp=t&chls=5|5|5&chma=5,5,5,5|15,20&chtt=Investment+Return+Planning+(+5+Years+)&chts=AA0033,15.5" );
				window.add( image );
				window.show();
			}
		} ) );

		buttonBar.add( new Button( "Investment Idealistic Plan", new SelectionListener<ButtonEvent>()
		{
			public void componentSelected( ButtonEvent ce )
			{
				Window window = new Window();
				window.setSize( 720, 430 );
				Image image = new Image();
				String url = "http://chart.apis.google.com/chart?chf=bg,lg,60,FFCC33,0,C3D9FF,1&chxl=1:|EPF+%2F+PPF|LIC+Premium|POSS|NSC|NSS|ELSS|Taxsaver+FD|NHB&chxr=0,0,50|1,8,0&chxt=x,y&chbh=a,5,15&chs=700x400&cht=bhg&chco=0000FF,008000&chds=0,50,0,50&chd=t:5,10,30,6,10,3,5,31|$nhb$,$fd$,$elss$,$nss$,$nsc$,$poss$,$lic$,$pf$&chdl=Ideal+investment|Your+Investment&chdlp=t&chg=5,0&chma=0,0,5|5&chtt=Investment+Idealistic+Plan&chts=FF0000,11.5";
				image.setUrl( getResovedUrl( url, groupModel.getSection80CModel() ) );
				window.add( image );
				window.show();
			}
		} ) );

		setBottomComponent( buttonBar );
	}

	protected String getResovedUrl( String url, Section80CModel section80CModel )
	{
		Integer pf = getPercentage( section80CModel.getPF() );
		Integer lic = getPercentage( section80CModel.getLIC() );
		Integer poss = getPercentage( section80CModel.getPostOffice() );
		Integer nsc = getPercentage( section80CModel.getNSC() );
		Integer nss = getPercentage( section80CModel.getNSS() );
		Integer elss = getPercentage( section80CModel.getMutualFund() );
		Integer fd = getPercentage( section80CModel.getFD() );
		Integer nhb = getPercentage( section80CModel.getNHB() );

		url = url.replace("$pf$", pf.toString() );
		url = url.replace( "$lic$", lic.toString() );
		url = url.replace( "$poss$", poss.toString() );
		url = url.replace( "$nsc$", nsc.toString() );
		url = url.replace( "$nss$", nss.toString() );
		url = url.replace( "$elss$", elss.toString() );
		url = url.replace( "$fd$", fd.toString() );
		url = url.replace( "$nhb$", nhb.toString() );

		return url;
	}

	private int getPercentage( Integer value )
	{
		if ( value == null || value == 0 )
			return 0;

		return (int)((double)value / Section80CItem.TOTAL80CLIMIT * 100);
	}

	private void addCollapsiblePanel( ContentPanel tabItem )
	{
		FormPanel formPanel = new FormPanel();
		ParentItem parentTabItem = ( ParentItem ) tabItem;
		formPanel.setLabelWidth( 200 );
		formPanel.setCollapsible( true );
		formPanel.setHeading( ( String ) parentTabItem.model.get( "displayString" ) );
		parentTabItem.setNonZeroMode( true );
		parentTabItem.addFormComponents( formPanel, false );
		parentTabItem.addTotalComponents( formPanel );
		parentTabItem.setNonZeroMode( false );
		if ( formPanel.getItems().size() != 0 )
			add( formPanel );

		FormBinding formBinding = new FormBinding( formPanel );
		formBinding.autoBind();
		formBinding.bind( parentTabItem.model );
		formPanel.collapse();
	}

	private void addTaxCalculationPanel()
	{
		taxCalculationPanel = new FormPanel();
		taxCalculationPanel.setLabelWidth( 200 );
		taxCalculationPanel.setHeading( "Total Payable Tax" );
		taxCalculationPanel.add( new UIHelper( null ).getNumberField( "Total Income", Const.CALCULATED_INCOME, false ) );
		taxCalculationPanel.add( new UIHelper( null ).getNumberField( "Taxable Income", Const.TAXABLE_INCOME, false ) );
		taxCalculationPanel.add( new UIHelper( null ).getNumberField( "Raw Tax", Const.RAW_TAX, false ) );
		taxCalculationPanel.add( new UIHelper( null ).getNumberField( "Surcharge", Const.SURCHARGE, false ) );
		taxCalculationPanel.add( new UIHelper( null ).getNumberField( "Education Cess", Const.EDU_CESS, false ) );
		taxCalculationPanel.add( new UIHelper( null ).getNumberField( "Payable Tax", Const.TAX_PAYABLE, false ) );
		add( taxCalculationPanel );
	}

	private void countTax()
	{
		int total = groupModel.getTaxableIncome().getTotal() - groupModel.getSection10Model().getTotal() - groupModel.getSection24Model().getTotal() - groupModel.getSection80CModel().getTotal() - groupModel.getSectionOthersModel().getTotal();
		final PayableTaxModel model = groupModel.getTaxCalculationModel();
		model.setCalculatedIncome( total < 0 ? 0 : total );
		int taxableIncome = model.getCalculatedIncome() - Collections.min( slabs.keySet() );
		model.setTaxableIncome( taxableIncome < 0 ? 0 : taxableIncome );
		model.setRawTax( getTax( model.getCalculatedIncome() ) );
		model.setSurcharge( 0 );
		model.setEducationCess( ( int ) ( model.getRawTax() * 0.03 ) );
		model.setTaxPayable( model.getRawTax() + model.getSurcharge() + model.getEducationCess() );
	}

	private void bind()
	{
		FormBinding formBinding = new FormBinding( taxCalculationPanel );
		formBinding.autoBind();
		formBinding.bind( groupModel.getTaxCalculationModel() );
	}

	private int getTax( int taxableIncome )
	{
		int tax = 0;
		for ( int slabValue : slabs.keySet() )
		{
			if ( taxableIncome > slabValue )
			{
				tax += ( taxableIncome - slabValue ) * ( slabs.get( slabValue ) / 100.0 );
				taxableIncome -= slabValue;
			}
		}
		return tax;
	}

	private Map<Integer, Integer> getSlabs()
	{
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		if ( isSeniorCitizen )
		{
			map.put( 500000, 30 );
			map.put( 300000, 20 );
			map.put( 240000, 10 );
		}
		else if ( isWoman )
		{
			map.put( 500000, 30 );
			map.put( 300000, 20 );
			map.put( 190000, 10 );
		}
		else
		{
			map.put( 500000, 30 );
			map.put( 300000, 20 );
			map.put( 160000, 10 );
		}
		return map;
	}

}
